﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;

namespace MLRobotic.Tower.Common
{
    // http://www.creativecodedesign.com/node/39
    // http://www.codeproject.com/Articles/21488/Serial-Port-Enumeration-on-Windows-Mobile
    // http://www.codeproject.com/Articles/1250/Another-serial-port-enumerator
    public static class SerialPortInfo
    {
        //Dictionary<string, string> friendlyPorts = BuildPortNameHash(SerialPort.GetPortNames());

        //Dictionary<string, string> friendlyPorts = BuildPortNameHash(SerialPort.GetPortNames());
        //foreach (KeyValuePair<string, string> kvp in friendlyPorts)
        //{
        //    textBox1.Text = textBox1.Text + Environment.NewLine + "Port '" + kvp.Key + "' is better known as '" + kvp.Value + "'";
        //}

        /// <summary>
        /// Begins recursive registry enumeration
        /// </summary>
        /// <param name="portsToMap">array of port names (i.e. COM1, COM2, etc)</param>
        /// <returns>a hashtable mapping Friendly names to non-friendly port values</returns>
        public static Dictionary<string, string> BuildPortNameHash(string[] portsToMap)
        {
            Dictionary<string, string> oReturnTable = new Dictionary<string, string>();
            //MineRegistryForPortName("Drivers\\Active", oReturnTable, portsToMap);
            //MineRegistryForPortName("Drivers\\BuiltIn", oReturnTable, portsToMap);
            MineRegistryForPortName("Software\\Microsoft\\Bluetooth\\Serial\\Ports", oReturnTable, portsToMap);
            //MineRegistryForPortName("", oReturnTable, portsToMap);
            return oReturnTable;
        }
        /// <summary>
        /// Recursively enumerates registry subkeys starting with startKeyPath looking for 
        /// "Device Parameters" subkey. If key is present, friendly port name is extracted.
        /// </summary>
        /// <param name="startKeyPath">the start key from which to begin the enumeration</param>
        /// <param name="targetMap">dictionary that will get populated with 
        /// nonfriendly-to-friendly port names</param>
        /// <param name="portsToMap">array of port names (i.e. COM1, COM2, etc)</param>
        static void MineRegistryForPortName(string startKeyPath, Dictionary<string, string> targetMap,
            string[] portsToMap)
        {
            if (targetMap.Count >= portsToMap.Length)
                return;
            using (RegistryKey currentKey = Registry.LocalMachine)
            {
                try
                {
                    System.Diagnostics.Debug.Write(startKeyPath + Environment.NewLine);

                    using (RegistryKey currentSubKey = currentKey.OpenSubKey(startKeyPath))
                    {
                        string[] currentNames = currentSubKey.GetValueNames();

                        foreach (string name in currentNames)
                        {
                            object portName = Registry.GetValue("HKEY_LOCAL_MACHINE\\" +
                                startKeyPath, name, null);

                            string val = portName == null ? "<empty>" : portName.ToString();
                            System.Diagnostics.Debug.Write("      " + name + " -- " + portName + Environment.NewLine);

                        }
                        string[] currentSubkeys = currentSubKey.GetSubKeyNames();


                        //if (currentSubkeys.Contains("Device Parameters") &&
                        //    startKeyPath != "SYSTEM\\CurrentControlSet\\Enum")
                        //{
                        //    object portName = Registry.GetValue("HKEY_LOCAL_MACHINE\\" +
                        //        startKeyPath + "\\Device Parameters", "PortName", null);
                        //    if (portName == null ||
                        //        portsToMap.Contains(portName.ToString()) == false)
                        //        return;
                        //    object friendlyPortName = Registry.GetValue("HKEY_LOCAL_MACHINE\\" +
                        //        startKeyPath, "FriendlyName", null);
                        //    string friendlyName = "N/A";
                        //    if (friendlyPortName != null)
                        //        friendlyName = friendlyPortName.ToString();
                        //    if (friendlyName.Contains(portName.ToString()) == false)
                        //        friendlyName = string.Format("{0} ({1})", friendlyName, portName);
                        //    targetMap[portName.ToString()] = friendlyName;
                        //}
                        //else
                        //{


                        foreach (string strSubKey in currentSubkeys)
                            MineRegistryForPortName(startKeyPath + "\\" + strSubKey, targetMap, portsToMap);
                        //}
                    }
                }
                catch (Exception)
                {
                    Console.WriteLine("Error accessing key '{0}'.. Skipping..", startKeyPath);
                }
            }
        }
    }
}
